<template>
	<div class="cost-wrap">
		<div class="module-box pb30">
			<div class="flex-between el-form-sub-title font-bold">商品概况</div>
			<div class="mb20 flex-between">
				<div>
					<span class="mr10">时间筛选</span>
					<el-date-picker
						v-model="dateRangeValue"
						type="daterange"
						unlink-panels
						range-separator="至"
						start-placeholder="开始时间"
						end-placeholder="结束时间"
						:disabled-date="disabledDate"
						format="YYYY-MM-DD"
						:shortcuts="shortcuts"
						@change="handleDateChange"
					/>
				</div>
				<el-button type="primary" plain @click="onChartExport" v-auth="'data:b2c:product:overview:export'">导出数据</el-button>
			</div>
			<div v-loading="loading">
				<div class="flex mt20">
					<div class="mr30">
						<div class="sub-title">
							商品总数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品总数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsAll }}</div>
						<div :class="getColor(data.goodsAllRate)">{{ data.goodsAllRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							在售商品<el-tooltip class="box-item" effect="light" content="筛选时间内，上架商品数量" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsOnline }}</div>
						<div :class="getColor(data.goodsOnlineRate)">{{ data.goodsOnlineRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							下架商品
							<el-tooltip class="box-item" effect="light" content="筛选时间内，下架商品数量" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsOffline }}</div>
						<div :class="getColor(data.goodsOfflineRate)">{{ data.goodsOfflineRate }}</div>
					</div>
				</div>
				<div class="flex mt20">
					<div class="mr30">
						<div class="sub-title">
							商品下单人数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品下单的人数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsOrder }}</div>
						<div :class="getColor(data.goodsOrderRate)">{{ data.goodsOrderRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品下单件数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品下单的件数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsOrderDetail }}</div>
						<div :class="getColor(data.goodsOrderDetailRate)">{{ data.goodsOrderDetailRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品下单金额<el-tooltip class="box-item" effect="light" content="筛选时间内，商品下单的金额" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.goodsOrderAmount) }}</div>
						<div :class="getColor(data.goodsOrderAmountRate)">{{ data.goodsOrderAmountRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品支付人数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品支付的人数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsPay }}</div>
						<div :class="getColor(data.goodsPayRate)">{{ data.goodsPayRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品支付件数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品支付的件数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsPayDetail }}</div>
						<div :class="getColor(data.goodsPayDetailRate)">{{ data.goodsPayDetailRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品支付金额<el-tooltip class="box-item" effect="light" content="筛选时间内，商品实际支付的金额" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.goodsPayAmount) }}</div>
						<div :class="getColor(data.goodsPayAmountRate)">{{ data.goodsPayAmountRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品退款人数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品成功退款的人数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsRefund }}</div>
						<div :class="getColor(data.goodsRefundRate)">{{ data.goodsRefundRate }}</div>
					</div>
					<div class="mr20">
						<div class="sub-title">
							商品退款件数<el-tooltip class="box-item" effect="light" content="筛选时间内，商品成功退款的件数" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ data.goodsRefundDetail }}</div>
						<div :class="getColor(data.goodsRefundDetailRate)">{{ data.goodsRefundDetailRate }}</div>
					</div>
					<div>
						<div class="sub-title">
							商品退款金额<el-tooltip class="box-item" effect="light" content="筛选时间内，商品成功退款的金额" placement="top">
								<el-icon color="#888" class="mt-3 ml5" style="vertical-align: middle">
									<QuestionFilled />
								</el-icon>
							</el-tooltip>
						</div>
						<div class="font20 mt10 mb5">{{ fenToYuan(data.goodsRefundAmount) }}</div>
						<div :class="getColor(data.goodsRefundAmountRate)">{{ data.goodsRefundAmountRate }}</div>
					</div>
				</div>
			</div>
		</div>
		<div class="module-box pb30 mt20" v-loading="loading">
			<div class="el-form-sub-title font-bold">商品销售趋势</div>
			<div class="chart-wrap">
				<LineCharts :option="chartsData" />
			</div>
		</div>
		<div class="module-box pb30 mt20">
			<div class="el-form-sub-title font-bold">商品销售排行</div>
			<div class="flex-end">
				<el-button type="primary" plain @click="onExport" v-auth="'data:b2c:product:sell:rank:export'">导出数据</el-button>
			</div>
			<ProTable ref="proTable" :columns="columns" :request-api="getTableList" :init-param="initParam" @sort-change="sortChange">
				<template #expand="scope">
					{{ scope.row }}
				</template>
			</ProTable>
		</div>

		<div class="module-box pb30 mt20">
			<div class="el-form-sub-title font-bold">分类销售排行</div>
			<div class="flex-end">
				<el-button type="primary" plain @click="onTypeExport" v-auth="'data:b2c:type:sell:rank:export'">导出数据</el-button>
			</div>
			<ProTable ref="proTypeTable" :columns="typeColumns" :request-api="getTypeTableList" :init-param="initParam" :pagination="false">
				<template #expand="scope">
					{{ scope.row }}
				</template>
			</ProTable>
		</div>
	</div>
</template>

<script setup lang="tsx" name="dataCost">
import { onMounted, ref, reactive, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import dayjs from 'dayjs';
import { NextLoading } from '/@/utils/loading';
import {
	fetchDataB2cGoods,
	fetchDataCatRankList,
	fetchDataGoodsRankList,
	fetchChartExport,
	fetchCatRankListExport,
	fetchGoodsRankListExport,
} from '/@/api/data';
import { useDownload } from '/@/hooks/useDownload';
import LineCharts from '/@/components/chart/lineCharts.vue';
import { fenToYuan } from '/@/utils/commonFunction';
import ProTable from '/@/components/ProTable/index.vue';
import { ProTableInstance, ColumnProps } from '/@/components/ProTable/interface';
const sortOder = ref('');
const sortType = ref('');
const dateRangeValue = ref([dayjs().subtract(30, 'day').format('YYYY-MM-DD'), dayjs().subtract(1, 'day').format('YYYY-MM-DD')]);
const data = ref<any>({
	goodsAll: '--',
	goodsAllRate: '--',
	goodsOffline: '--',
	goodsOfflineRate: '--',
	goodsOnline: '--',
	goodsOnlineRate: '--',
	goodsOrder: '--',
	goodsOrderRate: '--',
	goodsOrderAmount: '--',
	goodsOrderAmountRate: '--',
	goodsOrderDetail: '--',
	goodsOrderDetailRate: '--',
	goodsPay: '--',
	goodsPayRate: '--',
	goodsPayAmount: '--',
	goodsPayAmountRate: '--',
	goodsPayDetail: '--',
	goodsPayDetailRate: '--',
	goodsRefund: '--',
	goodsRefundRate: '--',
	goodsRefundAmount: '--',
	goodsRefundAmountRate: '--',
	goodsRefundDetail: '--',
	goodsRefundDetailRate: '--',
});
const loading = ref(true);
const chartsData = reactive<any>({
	data: [],
	xData: [],
	legend: [
		{ name: '商品下单人数', code: 'goodsOrder' },
		{ name: '商品下单件数', code: 'goodsOrderDetail' },
		{ name: '商品下单金额', code: 'goodsOrderAmount', type: 'price' },
		{ name: '商品支付人数', code: 'goodsPay' },
		{ name: '商品支付件数', code: 'goodsPayDetail' },
		{ name: '商品支付金额', code: 'goodsPayAmount', type: 'price' },
		{ name: '商品退款人数', code: 'goodsRefund' },
		{ name: '商品退款件数', code: 'goodsRefundDetail' },
		{ name: '商品退款金额', code: 'goodsRefundAmount', type: 'price' },
	],
});

const shortcuts = [
	{
		text: '昨天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24);
			end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
			return [start, end];
		},
	},
	{
		text: '近7天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
			end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
			return [start, end];
		},
	},
	{
		text: '近30天',
		value: () => {
			const end = new Date();
			const start = new Date();
			start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
			end.setTime(end.getTime() - 3600 * 1000 * 24 * 1);
			return [start, end];
		},
	},
];

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const proTable = ref<ProTableInstance>();

const proTypeTable = ref<ProTableInstance>();

// 如果表格需要初始化请求参数，直接定义传给 ProTable(之后每次请求都会自动带上该参数，此参数更改之后也会一直带上，改变此参数会自动刷新表格数据)
const initParam = reactive({});

// 如果你想在请求之前对当前请求参数做一些操作，可以自定义如下函数：params 为当前所有的请求参数（包括分页），最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getTableList"
const getTableList = (params: any) => {
	let data: any = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	if (sortOder.value) {
		data.orderType = sortOder.value === 'descending' ? '0' : '1';
		data.orderField = sortType.value == 'productNums' ? '0' : '1';
	}

	return fetchDataGoodsRankList(data);
};

// 表格配置项
const columns: ColumnProps<any>[] = [
	{
		type: 'index',
		label: '排名',
		minWidth: 120,
	},
	{
		prop: 'productId',
		label: '商品ID',
		minWidth: 160,
	},
	{
		prop: 'productName',
		label: '商品名称',
		minWidth: 120,
	},

	{
		prop: 'productNums',
		label: '支付件数',
		minWidth: 120,
		sortable: true,
	},
	{
		prop: 'productAmount',
		label: '支付金额',
		minWidth: 120,
		sortable: true,
		render: (scope) => {
			return fenToYuan(scope.row.productAmount);
		},
	},
];

const getTypeTableList = (params: any) => {
	let data = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};

	return fetchDataCatRankList(data);
};

const typeColumns: ColumnProps<any>[] = [
	{
		type: 'index',
		label: '排名',
		minWidth: 120,
	},
	{
		prop: 'productTypeName',
		label: '商品分类',
		minWidth: 160,
	},
	{
		prop: 'productNums',
		label: '支付件数',
		minWidth: 120,
		sortable: true,
	},
	{
		prop: 'productAmount',
		label: '支付金额',
		minWidth: 120,
		sortable: true,
		render: (scope) => {
			return fenToYuan(scope.row.productAmount);
		},
	},
	{
		prop: 'productAmountRate',
		label: '支付金额占比',
		minWidth: 120,
	},
];

const getColor = (str: string) => {
	const classStr = str ? (str == '增长0.00%' ? '' : str.includes('增长') ? 'grow-red' : str.includes('下降') ? 'grow—green' : '') : '';
	return classStr;
};

const handleDateChange = (val: any) => {
	const sameDay = dayjs(val[0]).isSame(val[1], 'day');
	if (sameDay && !dayjs(val[0]).isSame(dayjs().subtract(1, 'day'), 'day')) {
		ElMessage.warning('开始日期和结束日期不能相同，请重新选择日期');
		return;
	}
	getChartdata();
	proTable.value?.getTableList();
	proTypeTable.value?.getTableList();
};

const disabledDate = (time: Date) => {
	return time.getTime() > Date.now();
};

const getChartdata = async () => {
	loading.value = true;
	const params = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	chartsData.xData = [];
	chartsData.data = [];
	const res: any = await fetchDataB2cGoods(params);
	data.value = res.data.data;
	chartsData.legend.map((i: any, index: number) => {
		const arr: any = [];
		res.data.chartsData.forEach((item: any) => {
			if (index == 0) {
				chartsData.xData.push(item.reportDate);
			}
			arr.push(i.type === 'price' ? fenToYuan(item[i.code]) : item[i.code]);
		});
		chartsData.data.push(arr);
	});
	loading.value = false;
};

const sortChange = ({ column, prop, order }: any) => {
	sortOder.value = order;
	sortType.value = prop;
	proTable.value?.getTableList();
};

// 图表数据导出
const onChartExport = () => {
	let data: any = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	ElMessageBox.confirm('确认导出数据?', '温馨提示', { type: 'warning' }).then(() => useDownload(fetchChartExport, '商品概况数据', data));
};

// 保存并导出
const onExport = () => {
	let data: any = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	if (sortOder.value) {
		data.orderType = sortOder.value === 'descending' ? '0' : '1';
		data.orderField = sortType.value == 'productNums' ? '0' : '1';
	}
	ElMessageBox.confirm('确认导出数据?', '温馨提示', { type: 'warning' }).then(() => useDownload(fetchGoodsRankListExport, '商品销售排行列表', data));
};

// 保存并导出
const onTypeExport = () => {
	let data: any = {
		startTime: dayjs(dateRangeValue.value[0]).format('YYYY-MM-DD'),
		endTime: dayjs(dateRangeValue.value[1]).format('YYYY-MM-DD'),
	};
	ElMessageBox.confirm('确认导出数据?', '温馨提示', { type: 'warning' }).then(() => useDownload(fetchCatRankListExport, '分类销售排行列表', data));
};

// 页面加载时
onMounted(() => {
	getChartdata();
	NextLoading.done();
});
</script>

<style lang="scss">
.cost-wrap {
	.module-box {
		background: var(--el-color-white);
		padding: 20px;
		border-radius: var(--el-border-radius-round);
		box-sizing: border-box;
		overflow: hidden;
		.time {
			background: #f2f5f8;
			height: 32px;
			line-height: 32px;
			border-radius: 18px;
			font-size: 14px;
			font-weight: 400;
			padding: 0 16px;
			color: rgba($color: #000000, $alpha: 0.7);
			flex-shrink: 0;
		}
		.table-main {
			padding: 0;
		}
	}
	.sub-title {
		color: #666;
	}
	.grid {
		display: flex;
	}
	.grid-content {
		width: 20%;
	}
	.chart-wrap {
		height: 300px;
		width: 100%;
	}
}
</style>
